#include "UserLoginSection1.hpp"
#include "MyLogger.hpp"
#include "MySQLclient.hpp"
#include "Configuration.hpp"
#include "nlohmann/json.hpp"
#include <string.h>
#include <iostream>
#include <string>
using std::cout;
using std::endl;
using namespace std;
namespace wd
{
void UserLoginSection1::process()
{
    //先校验数据包类型客户端登录阶段1的请求
    if(_packet._type!=TASK_TYPE_LOGIN_SECTION1)
    {
        LOG_INFO("阶段1请求失败%d",_packet._type);
        TLV resp(TASK_TYPE_LOGIN_SECTION1_RESP_ERROR,11,"Invalid type");
        _conn->sendInLoop(resp);
        return;
    }

     // 新增：解析JSON格式的用户名
    using json = nlohmann::json;
    string username;
    try {
        json j = json::parse(_packet._msg);
        username = j["username"].get<string>(); // 提取真实用户名
    } catch (...) {
        LOG_ERROR("用户名格式错误（非JSON）：%s", _packet._msg.c_str());
        TLV resp(TASK_TYPE_LOGIN_SECTION1_RESP_ERROR, 15, "Invalid format");
        _conn->sendInLoop(resp);
        return;
    }

    LOG_INFO("阶段1获取用户名%s", username.c_str()); // 日志输出解析后的用户名
    
    //连接数据库
    MySQLclient mysql;
    Configuration* conf=Configuration::getInstance();
    if(!mysql.connect(conf->get("db_host"),
                      stoi(conf->get("db_port")),
                      conf->get("db_user"),
                      conf->get("db_pwd"),
                      conf->get("db_name")))
    {
       LOG_INFO("连接数据库失败");
       TLV resp(TASK_TYPE_LOGIN_SECTION1_RESP_ERROR,12,"System error");
        _conn->sendInLoop(resp);
        return;
    }

    //连接数据库查看用户是否存在并获取盐值
    std::string sql = "SELECT setting FROM user_registry WHERE name = ?"; // 参数化查询防注入
    MYSQL_STMT *stmt=mysql_stmt_init(&mysql._conn);
    if(!stmt||mysql_stmt_prepare(stmt,sql.c_str(),sql.size())!=0)
    {
       LOG_ERROR("查询失败",mysql_stmt_error(stmt));
       mysql_stmt_close(stmt);
       TLV resp(TASK_TYPE_LOGIN_SECTION1_RESP_ERROR,12,"System error");
        _conn->sendInLoop(resp);
        return;
    }

    //绑定用户名
    MYSQL_BIND bind;
    memset(&bind,0,sizeof(bind));
    bind.buffer_type=MYSQL_TYPE_STRING;
    bind.buffer=(char*)username.c_str();
    bind.buffer_length=username.size();
    if(mysql_stmt_bind_param(stmt,&bind)!=0)
    {
       LOG_ERROR("绑定失败%s",mysql_stmt_error(stmt));
       mysql_stmt_close(stmt);
       TLV resp(TASK_TYPE_LOGIN_SECTION1_RESP_ERROR,12,"System error");
        _conn->sendInLoop(resp);
        return;
    }

    //执行查询并获取结果
    mysql_stmt_execute(stmt);//将绑定的参数（用户名）发送到服务器执行查询
    //获取查询结果的元数据（列信息）
    MYSQL_RES *res=mysql_stmt_result_metadata(stmt);
    //创建 MYSQL_BIND 结构用于接收结果
    MYSQL_BIND resultBind;
    memset(&resultBind,0,sizeof(resultBind));


    //缓冲区
    char settingBuf[100]={0};
    unsigned long settinglen;
    resultBind.buffer_type=MYSQL_TYPE_STRING;
    //数据缓冲区
    resultBind.buffer=settingBuf;
    resultBind.buffer_length=sizeof(settingBuf);
    //实际长度指针
    resultBind.length=&settinglen;
    //绑定结果到缓冲区
    mysql_stmt_bind_result(stmt,&resultBind);


    //获取行
    string setting;
    if(mysql_stmt_fetch(stmt)==0)
    {
        setting=string(settingBuf,settinglen);
    }

    //释放资源
    mysql_stmt_close(stmt);
    mysql_free_result(res);

    //处理查询结果返回盐值或错误
    if(setting.empty())
    {
       LOG_WARN("用户名没有找到%s",username.c_str());
       TLV resp(TASK_TYPE_LOGIN_SECTION1_RESP_ERROR,13,"User not found");
        _conn->sendInLoop(resp);
    }
    else
    {
      LOG_INFO("LoginSection1: send salt for %s-%s" ,username.c_str(),setting.c_str());
        TLV resp(TASK_TYPE_LOGIN_SECTION1_RESP_OK, setting.size(), setting.c_str());
        _conn->sendInLoop(resp);
    }
}
}
